#include "Sprite.h"

const int VERTEXT_COUNT = 4;
const int PRIM_COUNT = 2;

/*-----------------------------------------------------------------------------------------------*/
Sprite::Sprite(const std::string& name) : Entity(name)
{
   m_pVertices = new TextureVertex[VERTEXT_COUNT];

   m_pVertices[0].setVertex(-0.5f,  0.5f, 0.0f, 0.0f, 0.0f);
   m_pVertices[1].setVertex(-0.5f, -0.5f, 0.0f, 0.0f, 1.0f);
   m_pVertices[2].setVertex( 0.5f,  0.5f, 0.0f, 1.0f, 0.0f);
   m_pVertices[3].setVertex( 0.5f, -0.5f, 0.0f, 1.0f, 1.0f);
}
/*-----------------------------------------------------------------------------------------------*/
bool Sprite::setTextureArea( UINT positionX, UINT positionY, UINT width, UINT height )
{
   if( !m_pTexture )
   {
      return false;
   }
   
   float texWidth = static_cast<float>( m_pTexture->getWidth() );
   float texHeight = static_cast<float>( m_pTexture->getHeight() );

   float U1 = positionX / texWidth;
   float V1 = positionY / texHeight;

   float U2 = (positionX + width) / texWidth;
   float V2 = (positionY + height) / texHeight;

   TextureVertex* pTextureVertex;
   
   pTextureVertex = &(m_pVertices[0]);
   pTextureVertex->u = U1;
   pTextureVertex->v = V1;

   pTextureVertex = &(m_pVertices[1]);
   pTextureVertex->u = U1;
   pTextureVertex->v = V2;

   pTextureVertex = &(m_pVertices[2]);
   pTextureVertex->u = U2;
   pTextureVertex->v = V1;

   pTextureVertex = &(m_pVertices[3]);
   pTextureVertex->u = U2;
   pTextureVertex->v = V2;

   return true;
}
/*-----------------------------------------------------------------------------------------------*/
void Sprite::draw(Renderer* renderer)
{
   assert(m_pTexture);

   Entity::draw(renderer);

   if( renderer->bindTexture(m_pTexture) )
   {
      renderer->DrawElements( VERTEXT_COUNT, m_pVertices, PRIM_COUNT, TRIANGLE_STRIP );
   }
   else
   {
      assert(0);
   }
}
/*-----------------------------------------------------------------------------------------------*/
void Sprite::clone (Sprite* sprite)
{
   if(sprite == this)
   {
      return;
   }

   sprite->setTexture(m_pTexture);

   for(UINT i = 0; i < VERTEXT_COUNT; ++i)
   {
      sprite->m_pVertices[i] = m_pVertices[i];
   }

   sprite->Scale(this->getScale());

   sprite->m_animationMap = m_animationMap;


}
/*-----------------------------------------------------------------------------------------------*/
bool Sprite::addAnimationInfo(std::string name, AnimationInfo::AnimationInfoPtr animationInfo)
{
   AnimationInfo::AnimationInfoPtr pAnimInfo = m_animationMap[name];

   if( pAnimInfo.get() )
   {
      return false;
   }
   
   m_animationMap[name] = animationInfo;

   return true;
}
/*-----------------------------------------------------------------------------------------------*/
bool Sprite::removeAnimationInfo(std::string name)
{
   AnimationInfo::AnimationInfoPtr pAnimInfo = m_animationMap[name];

   if( !pAnimInfo.get() )
   {
      return false;
   }

   m_animationMap.erase(name);
   
   return true;
}
/*-----------------------------------------------------------------------------------------------*/
bool Sprite::setAnimation(std::string name)
{
   if ( m_pCurrentAnimation )
   {
      m_pCurrentAnimation = NULL;
   }
   
   AnimationInfo::AnimationInfoPtr pAnimInfo = m_animationMap[name];

   if( !pAnimInfo.get() )
   {
      std::cout << "Set Animation failed" << std::endl;
      return false;
   }

   m_pCurrentAnimation = new Animation(pAnimInfo);

return true;
}
/*-----------------------------------------------------------------------------------------------*/
void Sprite::update(float deltaTime)
{
   Entity::update(deltaTime);

   if (!m_pCurrentAnimation)
   {
      return;
   }

   m_pCurrentAnimation->update(deltaTime);

   unsigned int currentFrame = m_pCurrentAnimation->getCurrentFrame();
   const Frame& frame = m_pCurrentAnimation->getAnimationInfo()->getFrame(currentFrame);

   setTextureArea( frame.x, frame.y, frame.width, frame.height );
}
/*-----------------------------------------------------------------------------------------------*/
void Sprite::onCollision(Entity* collider)
{
//   float randX = rand() % 100;
//   float randY = rand() % 100;
//   collider->Translate(randX,randY);
}